{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 记忆增强检索的示例\n",
    "\n",
    "本节我们将深入探讨如何通过集成记忆组件，增强我们的数据连接模块LEDVR工作流中的数据检索能力，从而提升QA问答应用的回答质量。我们将以《链》章节中的代码案例为基础，介绍如何在已有的检索器基础上，添加记忆组件，使ConversationalRetrievalChain链组件具有“记忆”能力。\n",
    "\n",
    "在此基础上，我们的案例应用将得以进一步提升。以LUA语言开发者在线文档问答为例，通过增强后的链组件，我们的程序不仅能在 http://developers.mini1.cn/wiki/luawh.html 中找到相关的文档内容，准确回答如“LUA宿主语言是什么”等问题，更能够记住用户在对话中的相关信息，如用户的名字，从而对更多复杂的问题提供更准确的答复。例如，当用户在问完几轮关于LUA语言编程的问题之后，如果他们再次提到他们的名字或引用他们之前提到的信息，增强后的ConversationalRetrievalChain链组件能够记住并理解这些信息，提供更加精确和个性化的回答。\n",
    "\n",
    "希望读者能够理解并掌握如何将记忆组件与链组件集成，从而实现数据检索能力的增强，提升QA问答应用的回答质量。同时，我们也将向读者展示如何通过增加记忆组件，使我们的程序更具人性化，能够更好地满足用户的需求。使用加载器开始，到 ConversationalRetrievalChain 的运行都与《链》章节一样。如果你已经很熟悉这段代码，可以直接跳到 ConversationalRetrievalChain 运行代码之后阅读。\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，我们需要从网络加载文档。这可以通过使用WebBaseLoader来完成：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.document_loaders import WebBaseLoader\n",
    "openai_api_key=\"\"\n",
    "loader = WebBaseLoader(\"http://developers.mini1.cn/wiki/luawh.html\")\n",
    "data = loader.load()\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "你也可以选择其他的加载器和其他的文档资源。接下来，我们需要创建一个嵌入模型实例的包装器，这可以使用OpenAIEmbeddings完成："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "from langchain.embeddings.openai import OpenAIEmbeddings\n",
    "embedding = OpenAIEmbeddings(openai_api_key=openai_api_key)\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后，我们需要将文档切割成块，这可以通过使用RecursiveCharacterTextSplitter来完成：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)\n",
    "splits = text_splitter.split_documents(data)\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接着，我们需要创建一个向量存储库，这里我们选择使用FAISS：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.vectorstores import FAISS\n",
    "vectordb = FAISS.from_documents(documents=splits,embedding=embedding)\n",
    "\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在我们有了一个向量存储库，我们可以用它来创建一个检索器 retriever，LEDVR 工作流就结束了。整个检索器便是LEDVR工作流的“胜利果实”：\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "retriever = vectordb.as_retriever()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从这里开始，我们可以将检索器加入到链中。首先，我们需要创建一个LLM 模型包装器，并通过ConversationalRetrievalChain.from_llm方法创建一个ConversationalRetrievalChain链组件的实例："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "from langchain.chat_models import ChatOpenAI\n",
    "from langchain.chains import ConversationalRetrievalChain\n",
    "llm = ChatOpenAI(openai_api_key=openai_api_key,temperature=0, model=\"gpt-3.5-turbo-0613\")\n",
    "qa = ConversationalRetrievalChain.from_llm(llm, retriever)\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "至此，我们已经完成了一个相当复杂的链 ConversationalRetrievalChain。这个链是我们目前了解的最复杂的链组件，它承担了会话和检索文档的两个重要职责。通过这个链，我们可以用如下的方式来查询问题："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'LUA的宿主语言通常是C或C++。'"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"LUA的宿主语言是什么？\"\n",
    "result = qa({\"question\": query,\"chat_history\":[]})\n",
    "result[\"answer\"]"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 记忆增强检索的代码开始"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "先导入我们的 ConversationBufferMemory 类，这个类实例化的组件时最常见的组件，组件的工作方式也非常简单，仅仅是将所有的聊天记录保存起来，并没有使用算法做截取或者提炼压缩。在提示词模板中可以看到所有的聊天记录。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.memory import ConversationBufferMemory\n",
    "memory = ConversationBufferMemory(memory_key=\"chat_history\",return_messages=True)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们看看初始化后，记忆组件里保存着什么记录。因为我们刚刚初始化，所以是[]。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.chat_memory.messages"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们使用 add_user_message 添加一个人类的消息，向程序介绍我的名字。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "memory.chat_memory.add_user_message(\"我是李特丽\")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第一次打印 memory.chat_memory.messages 时为[], 当我推送一条自我介绍后，我们可以看到添加了一条 HumanMessage 消息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[HumanMessage(content='我是李特丽', additional_kwargs={}, example=False)]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.chat_memory.messages"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'chat_history': [HumanMessage(content='我是李特丽', additional_kwargs={}, example=False)]}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.load_memory_variables({})"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们采用最直接的方式来演示记忆组件是如何与链组件共同工作的。从提示词模板出发，逐步增加组件的方式，展示这个工作机制。这一次我们使用的链组件是 load_qa_chain。这个链组件的优势在于专门用于QA问答，对于合并文档链组件不必掌握这些链的使用方法，只要在这个链上指定类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains.question_answering import load_qa_chain\n",
    "from langchain.prompts import PromptTemplate"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用向量存储库实例 的 similarity_search 方法，测试是否可以检索到与问题相关的文档了。我们可以打印 len(docs)， 看看这个问题搜索到了几个文档片段。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"LUA 的宿主语言是什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "len(docs)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "打印 docs 显示："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Document(page_content='Lua提供了非常易于使用的扩展接口和机制：由宿主语言(通常是C或C++)提供这些功能，Lua可以使用它们，就像是本来就内置的功能一样。 其它特性:', metadata={'source': 'http://developers.mini1.cn/wiki/luawh.html', 'title': '什么是Lua编程 | 开发者脚本帮助文档', 'description': '迷你世界开发者接口文档', 'language': 'zh-CN'}),\n",
       " Document(page_content='快速上手  开发者脚本怎么使用如何编辑脚本基础入门  什么是Lua编程Lua基本语法Lua数据类型Lua的变量Lua的循环语句流程控制语句（条件语句）Lua函数Lua运算符Lua字符串Lua数组Lua table(表)基础脚本示例及解读基础学习案例中级开发者  脚本是怎么运行的？迷你世界API接口  学习案例高手的世界  游戏数据类型小游戏开发《争分夺秒》小游戏开发《坦克对战》迷你世界ID查询  迷你世界ID查询脚本常见问题  开发者常见问题更新记录  更新日志   # 什么是Lua编程 以下部分内容引用自：https://www.runoob.com/lua/ # lua语言简介 概述 Lua是一种轻量小巧的脚本语言，用标准C语言编写并以源代码形式开放， 其设计目的是为了嵌入应用程序中，从而为应用程序提供灵活的扩展和定制功能。 特点 轻量级、可扩展，等等 轻量级: 它用标准C语言编写并以源代码形式开放，编译后仅仅一百余K，可以很方便的嵌入别的程序里。 可扩展:', metadata={'source': 'http://developers.mini1.cn/wiki/luawh.html', 'title': '什么是Lua编程 | 开发者脚本帮助文档', 'description': '迷你世界开发者接口文档', 'language': 'zh-CN'}),\n",
       " Document(page_content='什么是Lua编程 | 开发者脚本帮助文档\\n\\n\\n\\n\\n\\n\\n\\n  开发者脚本帮助文档   \\n  API接口查询\\n\\n  迷你世界官网\\n   \\n  星启计划\\n      \\n  API接口查询', metadata={'source': 'http://developers.mini1.cn/wiki/luawh.html', 'title': '什么是Lua编程 | 开发者脚本帮助文档', 'description': '迷你世界开发者接口文档', 'language': 'zh-CN'}),\n",
       " Document(page_content='# Lua数据类型 数据名称 用法描述 nil 表示一个无效值(在条件表达式中相当于false) boolean 布尔值,包含两个值：false和true number 实数,表示双精度类型的实浮点数,也可以是整数 string 字符串,由一对单引号或双引号来表示 table Lua的一种数据结构，可用来创建不同的数据类型，如：数组、字典等 function 由 C 或 Lua 编写的函数 userdata 表示任意存储在变量中的C数据结构 thread 表示执行的独立线路，用于执行协同程序 # Lua的变量 变量概述 什么是变量？ 变量在使用前，必须在代码中进行声明，即创建该变量。 编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区，用于存储变量的值。 Lua 变量有三种类型：全局变量、局部变量、表中的域。 Lua 中的变量全是全局变量，那怕是语句块或是函数里，除非用 local 显式声明为局部变量。 局部变量的作用域为从声明位置开始到所在语句块结束。 变量的默认值均为 nil。 \\xa0a = 5               -- 全局变量', metadata={'source': 'http://developers.mini1.cn/wiki/luawh.html', 'title': '什么是Lua编程 | 开发者脚本帮助文档', 'description': '迷你世界开发者接口文档', 'language': 'zh-CN'})]"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "docs"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用提示模板包装器，我们自定义一个提示词模板字符串。提示词内容四部分：一是对模型的指导词：“请你回答问题的时候，请依据文档内容和聊天记录回答，如果在其中找不到相关信息或者答案，请回答不知道。” ； 二是用问题检索到的相关文档内容：“文档内容是：{context}” ；三是记忆组件输出的记忆内容：“聊天记录是：{chat_history}” ；四是用户的输入： “Human: {human_input}”。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "template = \"\"\"你是说中文的chatbot.\n",
    "\n",
    "请你回答问题的时候，请依据文档内容和聊天记录回答，如果在其中找不到相关信息或者答案，请回答不知道。\n",
    "\n",
    "文档内容是：{context}\n",
    "\n",
    "聊天记录是：{chat_history}\n",
    "Human: {human_input}\n",
    "Chatbot:\"\"\"\n",
    "\n",
    "prompt = PromptTemplate(\n",
    "    input_variables=[\"chat_history\", \"human_input\", \"context\"], template=template\n",
    ")\n",
    "memory = ConversationBufferMemory(memory_key=\"chat_history\", input_key=\"human_input\")\n",
    "chain = load_qa_chain(\n",
    "    llm=llm, chain_type=\"stuff\", memory=memory, prompt=prompt\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'output_text': 'Lua的宿主语言通常是C或C++。'}"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"LUA 的宿主语言是什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "chain({\"input_documents\": docs, \"human_input\": query}, return_only_outputs=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'output_text': '我是一个中文的chatbot。'}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"我的名字是李特丽。你叫什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "chain({\"input_documents\": docs, \"human_input\": query}, return_only_outputs=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'output_text': 'Lua的循环语句有while循环、for循环和repeat...until循环。'}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"LUA 的循环语句是什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "chain({\"input_documents\": docs, \"human_input\": query}, return_only_outputs=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n",
      "Retrying langchain.embeddings.openai.embed_with_retry.<locals>._embed_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-embedding-ada-002 in organization org-VEnNKTtyYXEBdaVF7u4kNojB on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'output_text': '你的名字是李特丽。'}"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"我的名字是什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "chain({\"input_documents\": docs, \"human_input\": query}, return_only_outputs=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Human: LUA 的宿主语言是什么？\n",
      "AI: Lua的宿主语言通常是C或C++。\n",
      "Human: 我的名字是李特丽。你叫什么？\n",
      "AI: 我是一个中文的chatbot。\n",
      "Human: LUA 的循环语句是什么？\n",
      "AI: Lua的循环语句有while循环、for循环和repeat...until循环。\n",
      "Human: 我的名字是什么？\n",
      "AI: 你的名字是李特丽。\n"
     ]
    }
   ],
   "source": [
    "print(chain.memory.buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'output_text': '你的名字是李特丽。'}"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = \"我的名字是什么？\"\n",
    "docs = vectordb.similarity_search(query)\n",
    "chain({\"input_documents\": docs, \"human_input\": query}, return_only_outputs=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
